1   /*
2    * Copyright (C) 2011 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.cache;
18  
19  import com.google.common.annotations.Beta;
20  import com.google.common.collect.ImmutableMap;
21  import com.google.common.collect.Maps;
22  import com.google.common.util.concurrent.UncheckedExecutionException;
23  
24  import java.util.Map;
25  import java.util.concurrent.Callable;
26  import java.util.concurrent.ExecutionException;
27  
28  /**
29   * This class provides a skeletal implementation of the {@code Cache} interface to minimize the
30   * effort required to implement this interface.
31   *
32   * <p>To implement a cache, the programmer needs only to extend this class and provide an
33   * implementation for the {@link #get(Object)} and {@link #getIfPresent} methods.
34   * {@link #getUnchecked}, {@link #get(Object, Callable)}, and {@link #getAll} are implemented in
35   * terms of {@code get}; {@link #getAllPresent} is implemented in terms of {@code getIfPresent};
36   * {@link #putAll} is implemented in terms of {@link #put}, {@link #invalidateAll(Iterable)} is
37   * implemented in terms of {@link #invalidate}. The method {@link #cleanUp} is a no-op. All other
38   * methods throw an {@link UnsupportedOperationException}.
39   *
40   * @author Charles Fry
41   * @since 11.0
42   */
43  @Beta
44  public abstract class AbstractLoadingCache<K, V>
45      extends AbstractCache<K, V> implements LoadingCache<K, V> {
46  
47    /** Constructor for use by subclasses. */
48    protected AbstractLoadingCache() {}
49  
50    @Override
51    public V getUnchecked(K key) {
52      try {
53        return get(key);
54      } catch (ExecutionException e) {
55        throw new UncheckedExecutionException(e.getCause());
56      }
57    }
58  
59    @Override
60    public ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException {
61      Map<K, V> result = Maps.newLinkedHashMap();
62      for (K key : keys) {
63        if (!result.containsKey(key)) {
64          result.put(key, get(key));
65        }
66      }
67      return ImmutableMap.copyOf(result);
68    }
69  
70    @Override
71    public final V apply(K key) {
72      return getUnchecked(key);
73    }
74  
75    @Override
76    public void refresh(K key) {
77      throw new UnsupportedOperationException();
78    }
79  }